﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntitiesLayer;
using System.Transactions;
using System.Data.SqlClient;
using System.Data;
using DAL.Repositories;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using DAL.AbstractRepositories;

namespace DAL.Repositorios
{
    public class UsuarioManRepository : DAL.AbstractRepositories.AbstractRepository<Usuario>, DAL.Repositorios.IRepositoryUsuarioSesion<Usuario>
    {


        private static Dictionary<char, Func<int, DataRow, Usuario>> tipoUsuario;

        static UsuarioManRepository(){
            tipoUsuario = new Dictionary<char, Func<int, DataRow, Usuario>>();
            tipoUsuario.Add('C', ClienteRepository.crearCliente);
            tipoUsuario.Add('F', FuncionarioRepository.crearFuncionario);
        }

        public override void Insert(Usuario entity)
        {
            Inserted.Add(entity);
        }

        public override void Delete(Usuario entity)
        {
            Deleted.Add(entity);
        }

        public override void Update(Usuario entity)
        {
            Updated.Add(entity);
        }

        public override IEnumerable<Usuario> GetAll()
        {
            SqlCommand cmd = new SqlCommand();
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaListarUsuariosOpti");
            IList<Usuario> lista = new List<Usuario>();
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                char tipo = Convert.ToChar(dr["TipoUsuario"]);
                lista.Add( tipoUsuario[tipo](dr.Field<int>("IdUsuario"), dr));
            }

            return lista.Count > 0 ? lista : null;
        }

        public override Usuario GetById(int id)
        {
            Usuario usuario = null;

            DataSet ds = GetDataSetGenerico(DBNull.Value, id);

            foreach (DataRow dr in ds.Tables[0].Rows) {
                char tipo = Convert.ToChar(dr["TipoUsuario"]);
                
                usuario=tipoUsuario[tipo](id, dr);
            }
            
            return usuario;
        }

        public static DataSet GetDataSetGenerico(object tipo, object idUsuario) {
            
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@Tipo", tipo));
            cmd.Parameters.Add(new SqlParameter("@IdUsuario", idUsuario));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaConsultaGeneralUsuario ");

            return ds;
        
        }
        

        protected override void InsertEntity(Usuario u) {


            SqlParameter pfoto = new SqlParameter("@Foto", SqlDbType.Image);
        
            byte[] f = u.Foto.ToByte();
            pfoto.Value = (object)f ?? (object)DBNull.Value;
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@Identificacion", u.Identificacion));
            cmd.Parameters.Add(new SqlParameter("@Nombre", u.Nombre));
            cmd.Parameters.Add(new SqlParameter("@ClaveUsuario", u.GenerarClaveDefualt()));
            cmd.Parameters.Add(new SqlParameter("@PApellido", u.PApellido));
            cmd.Parameters.Add(new SqlParameter("@FechaNacimiento", u.FechaNacimiento));
            cmd.Parameters.Add(new SqlParameter("@FechaIngreso", u.FechaIngreso));
            cmd.Parameters.Add(new SqlParameter("@Genero", (char)u.Genero));
            cmd.Parameters.Add(pfoto);
            cmd.Parameters.Add(new SqlParameter("@Alias", u.Alias));
            cmd.Parameters.Add(new SqlParameter("@NombreUsuario", u.NombreUsuario));
            cmd.Parameters.Add(new SqlParameter("@DescTipoID", u.DiscripcionTipoId));
            cmd.Parameters.Add(new SqlParameter("@NombrePais", u.Nacionalidad));
            cmd.Parameters.Add(new SqlParameter("@IdRol", u.Rol.Id));
            cmd.Parameters.Add(new SqlParameter("@Estado", (char)u.Estado));
            cmd.Parameters.Add(new SqlParameter("@Tipo", u is Cliente ? 'C' : 'F'));
            cmd.Parameters.Add(new SqlParameter("@SApellido", u.SApellido));
            long id = DBAccess.ExecuteSPScalar(ref cmd, "PaRegistrarUsuario");

            this.IdAutoGenerados.Add(u, id);
          
        }

        protected override void UpdateEntity(Usuario u)
        {
            SqlParameter pfoto = new SqlParameter("@Foto", SqlDbType.Image);
            
            byte[] f = u.Foto.ToByte();
            pfoto.Value = (object)f ?? (object)DBNull.Value;
                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@IdUsuario", u.Id));
                cmd.Parameters.Add(new SqlParameter("@Identificacion", u.Identificacion));
                cmd.Parameters.Add(new SqlParameter("@Nombre", u.Nombre));
                cmd.Parameters.Add(new SqlParameter("@ClaveUsuario", (object)u.GenerarClaveDefualt() ?? (object)DBNull.Value));
                cmd.Parameters.Add(new SqlParameter("@PApellido", u.PApellido));
                cmd.Parameters.Add(new SqlParameter("@SApellido", u.SApellido));
                cmd.Parameters.Add(new SqlParameter("@FechaNacimiento", u.FechaNacimiento));
                cmd.Parameters.Add(new SqlParameter("@FechaIngreso", u.FechaIngreso));
                cmd.Parameters.Add(new SqlParameter("@Genero",(char)u.Genero));
                cmd.Parameters.Add(pfoto);
                cmd.Parameters.Add(new SqlParameter("@Alias", u.Alias));
                cmd.Parameters.Add(new SqlParameter("@NombreUsuario", u.NombreUsuario));
                cmd.Parameters.Add(new SqlParameter("@DescTipoID", u.DiscripcionTipoId));
                cmd.Parameters.Add(new SqlParameter("@NombrePais", u.Nacionalidad));
                cmd.Parameters.Add(new SqlParameter("@IdRol", u.Rol.Id));
                cmd.Parameters.Add(new SqlParameter("@Tipo", u.TipoCode));
                cmd.Parameters.Add(new SqlParameter("@Estado", u.EstadoCode));

                DBAccess.ExecuteSPNonQuery(ref cmd, "PaModificarUsuario");
            
        }

        protected  override void DeleteEntity(Usuario u)
        {

                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@IdUsuario", u.Id));
                DBAccess.ExecuteSPNonQuery(ref cmd, "PaEliminarUsuario");
        }

        public Usuario IniciarSesion(string pnombre, string pclave)
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@nombre_usu", pnombre));
            cmd.Parameters.Add(new SqlParameter("@clave_usu", pclave));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaIniciarSesion");
            Usuario usuario = null;

            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                char tipo = Convert.ToChar(dr["TipoUsuario"]);

                usuario = tipoUsuario[tipo](dr.Field<int>("IdUsuario"), dr);
            }

            return usuario;

        }
    }
}
